#include <predicate.h>
#include <sstream>

Predicate :: Predicate(Schema &_useMe, char *_fNAme)
{
	m_oPredSchema		 = new Schema(_useMe);
	m_iNumArray			 = new int[m_oPredSchema->GetAttrCount()];
	m_iaComparison		 = new int[m_oPredSchema->GetAttrCount()];
	
	FILE * pFile;
	pFile = fopen (_fNAme,"r");
	m_iCampareNumber = 0;
	int count1  = 0;
	int count2 = 0;
	int count3 = 0;
	char * fl;
	
	if (pFile == NULL)
	{
		fclose (pFile);
	}
	else
	{
		int count = 0;
		char memorySpace[300];
	
		int place = -1;
		int read = 0;
		while (!feof(pFile)) 
		{
			//char * put = new char[300];
			string put;
			fl = fgets (memorySpace, 300 , pFile);
			if(fl == NULL || (strncmp ("\n", memorySpace, strlen ("memorySpace")) == 0))
			{
				break;
			}
			char * first = strtok (memorySpace," \0\n");
			while (first != NULL)
			{
				if(count == 0)
				{
					m_iCampareNumber++;
					place = m_oPredSchema->GetPlace(first);
					if(place < 0)
					{
						cerr << "Predicate Error: The name could not be found in Schema "<< endl;
						exit(1);
					}
					//cout << "Name: " << memorySpace <<", Place " << place << endl;
					m_iNumArray[count1] = place;
					count1++;
				}
				else if(count == 1)
				{
					int com = 0;
					if(strncmp ("=",first, strlen ("=")) == 0)
					{
						//cout << "Name: " << memorySpace <<", I have equal: 0" << endl; 
						com = 0;
					}
					else if(strncmp ("<",first, strlen ("<")) == 0)
					{
						//cout << "Name: " << memorySpace <<", I have <: 1" << endl; 
						com = 1;
					}
					else
					{
						//cout << "Name: " << memorySpace <<", I have >: 2" << endl; 
						com = 2;
					}
					m_iaComparison[count2] = com;
					count2++;
				}
				else if(count >= 2)
				{
					//cout << "Name: " << memorySpace <<", Typee " << m_oPredSchema->GetType(place) << endl;
					if(count == 2)
					{
						put.append(first);
					}
					else if(first != NULL)
					{
						put.append(" ");
						put.append(first);
					}
					else if(first == NULL)
					{
					
					}
				}
				else
				{
					cout << "Something is wrong" << endl;
				}
				first = strtok (NULL," \0\n");
				count++;
				//cout << memorySpace << " , count = " << count << endl;
			}
			if(first == NULL)
			{
				Attribute att;
				Type ty =  m_oPredSchema->GetType(place);
				if(ty == Int || ty == Double)
				{
					/*
					stringstream ss (put);
					int * intVal;
					intVal  = new int;
					ss >> *intVal;
					
					att.SetData(intVal,ty);
					att.SetFree();
					//att.Print(ty);
					*/
				}
				/*else if(ty == Double)
				{
					stringstream ss (put);
					double * doubleVal;
					doubleVal = new double;
					ss >> *doubleVal;
					
					att.SetData(doubleVal,ty);
					att.SetFree();
					//att.Print(ty);
				}*/
				else
				{
					/*
					string put1 = put;
					string sub = put1.substr(1,put1.length()-3);
					char* charStringVal = new char[sub.length() + 1];
					memset(charStringVal, '\0', sub.length() + 1 );
					sub.copy(charStringVal, sub.length() + 1);
					
					att.SetData(charStringVal,ty);
					att.SetFree();
					//att.Print(ty);
					*/
					put = put.substr(1,put.length()-3);
				}
			
				//cout << put << endl;
				att.SetData(put,ty);
				att.Free();

				m_lAttList.push_back(att);
			}
			
			count = 0;
		}
		
		//cout << "I have how many comaprisons " << m_iCampareNumber << endl;
		fclose (pFile);
	}
	//m_rPRecord ->Print(*m_oPredSchema);
}	

Predicate :: ~Predicate()
{
	list<Attribute> :: const_iterator i;
	i=m_lAttList.begin();
	int x = 0;
	while(i!= m_lAttList.end())
	{
		Attribute at;
		at = *i;
		at.SetFree();
		i++;
	}
	m_lAttList.clear();
	delete [] m_iNumArray;
	delete [] m_iaComparison;
}

// returns 1 or TRUE if the predicate accepts the given record,
// and returns a 0 or FALSE if the predicate does not accept the
// given record
int Predicate :: Apply(Record &_toMe)
{
	int answerToPred = 1;
	list<Attribute> :: const_iterator i;
	int count = 0;
	i=m_lAttList.begin();
	while(i!= m_lAttList.end() && answerToPred == 1)
	{
		Attribute at;
		at = *i;
		answerToPred = _toMe.Compare(at,m_iNumArray[count],m_iaComparison[count],m_oPredSchema->GetType(m_iNumArray[count]));
		//cout <<"TYPE " << m_oPredSchema->GetType(m_iNumArray[count])<< ", answer: " << answerToPred << endl;
		count++;
		i++;
	}
	return answerToPred;
}

void Predicate :: Print(Schema &mySchema)
{
	list<Attribute> :: const_iterator i;
	i=m_lAttList.begin();
	int x = 0;
	while(i!= m_lAttList.end())
	{
		Attribute at;
		at = *i;
		at.Print(mySchema.GetType(m_iNumArray[x]));
		cout << "\t";
		x++;
		i++;
	}
	cout << endl;
}

